/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 2009 - 2012 Luca Mingardi.
 *
 * This file is part of jeeObserver.
 *
 * JeeObserver is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * JeeObserver is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */
package jeeobserver.server.settings;

import java.io.Serializable;

/**
 * The Interface Condition.
 *
 * @author Luca Mingardi
 * @version 4.0
 */
public abstract class Condition implements Serializable {

	 private static final long serialVersionUID = 40L;

	 /** The Constant OPERATOR_NO_CONDITION. */
	 public static final int OPERATOR_NO_CONDITION = 0;

	 /** The Constant OPERATOR_TEXT_EQUAL. */
	 public static final int OPERATOR_TEXT_EQUAL = 10;

	 /** The Constant OPERATOR_TEXT_NOT_EQUAL. */
	 public static final int OPERATOR_TEXT_NOT_EQUAL = 20;

	 /** The Constant OPERATOR_TEXT_CONTAINS. */
	 public static final int OPERATOR_TEXT_CONTAINS = 30;

	 /** The Constant OPERATOR_TEXT_NOT_CONTAINS. */
	 public static final int OPERATOR_TEXT_NOT_CONTAINS = 40;

	 /** The Constant OPERATOR_TEXT_BEGIN_WITH. */
	 public static final int OPERATOR_TEXT_BEGIN_WITH = 50;

	 /** The Constant OPERATOR_TEXT_END_WITH. */
	 public static final int OPERATOR_TEXT_END_WITH = 60;

	 /** The Constant OPERATOR_NUMBER_LESS_THAN. */
	 public static final int OPERATOR_NUMBER_LESS_THAN = 70;

	 /** The Constant OPERATOR_NUMBER_GREATER_THAN. */
	 public static final int OPERATOR_NUMBER_GREATER_THAN = 80;

	 /** The Constant OPERATOR_NUMBER_EQUAL. */
	 public static final int OPERATOR_NUMBER_EQUAL = 10;

	 /** The Constant OPERATOR_BOOLEAN_EQUAL. */
	 public static final int OPERATOR_BOOLEAN_EQUAL = 10;

	 /** The operator. */
	 private int operator;

	 public int getOperator() {
			return operator;
	 }

	 public void setOperator(int operator) {
			this.operator = operator;
	 }

	 public Condition(int operator) {
			this.operator = operator;
	 }

	 public static class BooleanCondition extends Condition implements Serializable {

			/** The Constant serialVersionUID. */
			private static final long serialVersionUID = 40L;

			private boolean value;

			/**
			 * Instantiates a new boolean condition.
			 *
			 * @param operator the operator
			 * @param value the value
			 */
			public BooleanCondition(int operator, boolean value) {
				 super(operator);

				 if (operator == Condition.OPERATOR_NO_CONDITION) {
						this.value = false;
				 } else {
						this.value = value;
				 }
			}

			/**
			 * Check value.
			 *
			 * @param valueToCheck the value to check
			 *
			 * @return true, if successful
			 */
			public boolean checkValue(boolean valueToCheck) {
				 if (this.getOperator() == Condition.OPERATOR_NO_CONDITION) {
						return true;
				 }

				 return valueToCheck == this.value;
			}
	 }

	 public static class NumberCondition extends Condition implements Serializable {

			/** The Constant serialVersionUID. */
			private static final long serialVersionUID = 40L;

			/** The operator. */
			private int operator = Condition.OPERATOR_NO_CONDITION;

			/** The value. */
			private double value;

			/**
			 * Instantiates a new number condition.
			 *
			 * @param operator the operator
			 * @param value the value
			 */
			public NumberCondition(int operator, double value) {
				 super(operator);
				 if (operator == Condition.OPERATOR_NO_CONDITION) {
						this.value = 0;
				 } else {
						this.value = value;
				 }
			}

			/**
			 * Check value.
			 *
			 * @param valueToCheck the value to check
			 *
			 * @return true, if successful
			 */
			public boolean checkValue(double valueToCheck) {
				 if (this.operator == Condition.OPERATOR_NO_CONDITION) {
						return true;
				 } else if (this.operator == Condition.OPERATOR_NUMBER_EQUAL) {
						return valueToCheck == this.value;
				 } else if (this.operator == Condition.OPERATOR_NUMBER_GREATER_THAN) {
						return valueToCheck > this.value;
				 } else if (this.operator == Condition.OPERATOR_NUMBER_LESS_THAN) {
						return valueToCheck < this.value;
				 }
				 return false;
			}
	 }

	 public static class SizeCondition extends NumberCondition {

			/** The Constant serialVersionUID. */
			private static final long serialVersionUID = 40L;

			/** The Constant SIZE_UNIT_B. */
			public static final int SIZE_UNIT_B = 0;

			/** The Constant SIZE_UNIT_KB. */
			public static final int SIZE_UNIT_KB = 1;

			/** The Constant SIZE_UNIT_MB. */
			public static final int SIZE_UNIT_MB = 2;

			/** The Constant SIZE_UNIT_GB. */
			public static final int SIZE_UNIT_GB = 3;

			/** The Constant SIZE_UNIT_TB. */
			public static final int SIZE_UNIT_TB = 4;

			/** The Constant B_BYTES. */
			private static final long B_BYTES = new Long(1).longValue();

			/** The Constant KB_BYTES. */
			private static final long KB_BYTES = new Long(1024).longValue();

			/** The Constant MB_BYTES. */
			private static final long MB_BYTES = SizeCondition.KB_BYTES * new Long(1024).longValue();

			/** The Constant GB_BYTES. */
			private static final long GB_BYTES = SizeCondition.MB_BYTES * new Long(1024).longValue();

			/** The Constant TB_BYTES. */
			private static final long TB_BYTES = SizeCondition.GB_BYTES * new Long(1024).longValue();

			/** The conversion size. */
			private static long conversionSize[] = new long[]{SizeCondition.B_BYTES, SizeCondition.KB_BYTES, SizeCondition.MB_BYTES, SizeCondition.GB_BYTES, SizeCondition.TB_BYTES};

			/** The unit. */
			private int unit;

			/**
			 * Instantiates a new size condition.
			 *
			 * @param operator the operator
			 * @param value the value
			 * @param unit the unit
			 */
			public SizeCondition(int operator, double value, int unit) {

				 super(operator, value);

				 if (operator == Condition.OPERATOR_NO_CONDITION) {
						this.unit = 0;
				 } else {
						this.unit = unit;
				 }
			}

			/**
			 * Check byte value.
			 *
			 * @param valueToCheck the value to check
			 *
			 * @return true, if successful
			 */
			public boolean checkByteValue(double valueToCheck) {
				 return super.checkValue(valueToCheck / SizeCondition.conversionSize[this.unit]);
			}

			/**
			 * Gets the unit.
			 *
			 * @return the unit
			 */
			public int getUnit() {
				 return this.unit;
			}

			/**
			 * Sets the unit.
			 *
			 * @param unit the new unit
			 */
			public void setUnit(int unit) {
				 this.unit = unit;
			}
	 }

	 public static class TextCondition extends Condition implements Serializable {

			/** The Constant serialVersionUID. */
			private static final long serialVersionUID = 40L;

			/** The value. */
			private String value;

			/**
			 * Instantiates a new text condition.
			 *
			 * @param operator the operator
			 * @param value the value
			 */
			public TextCondition(int operator, String value) {
				 super(operator);

				 if (operator == Condition.OPERATOR_NO_CONDITION) {
						this.value = null;
				 } else {
						this.value = value;
				 }
			}

			/**
			 * Check value.
			 *
			 * @param valueToCheck the value to check
			 *
			 * @return true, if successful
			 */
			public boolean checkValue(String valueToCheck) {

				 if (this.getOperator() == Condition.OPERATOR_NO_CONDITION) {
						return true;
				 } else if (this.getOperator() == Condition.OPERATOR_TEXT_EQUAL) {
						return valueToCheck.equals(this.value);
				 } else if (this.getOperator() == Condition.OPERATOR_TEXT_CONTAINS) {
						return valueToCheck.contains(this.value);
				 } else if (this.getOperator() == Condition.OPERATOR_TEXT_NOT_CONTAINS) {
						return !valueToCheck.contains(this.value);
				 } else if (this.getOperator() == Condition.OPERATOR_TEXT_BEGIN_WITH) {
						return valueToCheck.startsWith(this.value);
				 } else if (this.getOperator() == Condition.OPERATOR_TEXT_END_WITH) {
						return valueToCheck.endsWith(this.value);
				 } else if (this.getOperator() == Condition.OPERATOR_TEXT_NOT_EQUAL) {
						return !valueToCheck.equals(this.value);
				 }

				 return false;
			}

			/**
			 * Gets the value.
			 *
			 * @return the value
			 */
			public String getValue() {
				 return this.value;
			}

			/**
			 * Sets the value.
			 *
			 * @param value the new value
			 */
			public void setValue(String value) {
				 this.value = value;
			}
	 }

	 public static class TimePeriodCondition extends Condition implements Serializable {

			/** The Constant serialVersionUID. */
			private static final long serialVersionUID = 40L;

			/** The operator. */
			private int operator = Condition.OPERATOR_NO_CONDITION;

			/** The value. */
			private TimePeriod value;

			/**
			 * Instantiates a new time period condition.
			 *
			 * @param operator the operator
			 * @param value the value
			 */
			public TimePeriodCondition(int operator, TimePeriod value) {
				 super(operator);

				 if (operator == Condition.OPERATOR_NO_CONDITION) {
						this.value = null;
				 } else {
						this.value = value;
				 }
			}

			/**
			 * Check millis value.
			 *
			 * @param valueToCheck the value to check
			 *
			 * @return true, if successful
			 */
			public boolean checkMillisValue(double valueToCheck) {
				 if (this.operator == Condition.OPERATOR_NO_CONDITION) {
						return true;
				 } else if (this.operator == Condition.OPERATOR_NUMBER_GREATER_THAN) {
						return valueToCheck > this.getValue().getMillis();
				 } else if (this.operator == Condition.OPERATOR_NUMBER_LESS_THAN) {
						return valueToCheck < this.getValue().getMillis();
				 } else if (this.operator == Condition.OPERATOR_TEXT_EQUAL) {
						return valueToCheck == this.getValue().getMillis();
				 }

				 return false;
			}

			/**
			 * Check nanos value.
			 *
			 * @param valueToCheck the value to check
			 *
			 * @return true, if successful
			 */
			public boolean checkNanosValue(double valueToCheck) {
				 if (this.operator == Condition.OPERATOR_NO_CONDITION) {
						return true;
				 } else if (this.operator == Condition.OPERATOR_NUMBER_GREATER_THAN) {
						return valueToCheck > this.getValue().getNanos();
				 } else if (this.operator == Condition.OPERATOR_NUMBER_LESS_THAN) {
						return valueToCheck < this.getValue().getNanos();
				 } else if (this.operator == Condition.OPERATOR_TEXT_EQUAL) {
						return valueToCheck == this.getValue().getNanos();
				 }

				 return false;
			}

			/**
			 * Gets the value.
			 *
			 * @return the value
			 */
			public TimePeriod getValue() {
				 return this.value;
			}

			/**
			 * Sets the value.
			 *
			 * @param value the new value
			 */
			public void setValue(TimePeriod value) {
				 this.value = value;
			}
	 }
}